/**
 *
 */
package com.angel.common.helpers;

import java.text.NumberFormat;
import java.text.ParseException;
import java.util.List;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

/** The <code>ValidatorHelper.class</code> helps you to manage some validations string and numbers functions.
 *  All its methods are statics.
 *
 * @author William
 * @version
 */
public class ValidatorHelper {

	/** It is the logger for the class. */
	private static Logger logger = Logger.getLogger(ValidatorHelper.class);

	private ValidatorHelper(){
		super();
	}

	/** Set current log level.
	 *
	 * @param logLevel
	 */
	public static void setLogLevel(Level logLevel){
		logger.setLevel(logLevel);
	}

	/** Validate value string doesn't begin with numbers. If it doesn't begin with numbers, it returns true,
	 * otherwise it retuns false.
	 *
	 * @param value
	 * @return
	 */
	public static boolean isValidStringNotBeginWithNumbers(String value){
		boolean isValid = true;
		if(		StringHelper.beginsAtLeast(value, StringHelper.NUMBER_WEB_CHARACTERS) ||
				StringHelper.containsAtLeast(value, StringHelper.INVALID_WEB_CHARACTERS)){
			isValid = false;
		}
		return isValid;
	}

	/** Verify if value string (between min and max length) is a valid number.
	 *
	 * @param value
	 * @param minLength
	 * @param maxLength
	 * @return true if it is a valid number, otherwise it returns false.
	 */
	public static boolean isValidStringWithNumbers(String value, int minLength, int maxLength) {

		boolean result= true;

		value = StringHelper.trimComplete(value);

		/** Verify if the value has invalid symbols. */
		result = validateStringInvalidSymbols(value) && result;

		/** Verify if the value's length is between minLength and maxLength. */
		result = validateStringInvalidLength(value, minLength, maxLength) && result;

		/** Verify if the value is null or and empty string. */
		result = validateStringEmpty(value) && result;

		return result;
	}

	public static boolean isValidStringWithoutNumbers(String value, int minLength, int maxLength){

		/** Validate if the value with numbers is valid. */
		boolean result = isValidStringWithNumbers(value, minLength, maxLength);

		/** Validate if value contanis some number.*/
		result = validateStringNotContainsNumbers(value) && result;

		return result;
	}

	public static boolean isValidNumberWithoutString(String value, int minValue, int maxValue) {

		boolean isValid = validateNumberInvalidSymbolsAndStrings(value);

		if(isValid){
			NumberFormat numberFormat = NumberFormat.getCurrencyInstance();
			Number number = null;

			try {
				number = numberFormat.parse(value);
			} catch (ParseException e) {
				e.printStackTrace();
			}

			isValid = isValidNumber(number, minValue, maxValue);
		}

		return isValid;
	}

	public static boolean isValidNumber(Number value, int minValue, int maxValue) {
		boolean result= true;

		result = validateNumberSize(value, minValue, maxValue) && result;

		return result;
	}

	private static boolean validateStringNotContainsNumbers(String value){
		boolean result = true;
		if(StringHelper.containsAtLeast(value, StringHelper.NUMBER_WEB_CHARACTERS)){
			result = false;
		}
		return result;
	}

	private static boolean validateNumberInvalidSymbolsAndStrings(String value){
		boolean result = true;

		/** Verify if the value contains invalids symbols*/
		if(!StringHelper.isEmpty(value) &&
				(StringHelper.containsAtLeast(value, StringHelper.INVALID_WEB_CHARACTERS) || StringHelper.containsAtLeast(value, StringHelper.STRING_WEB_CHARACTERS))){

			result = false;
		}
		return result;
	}

	private static boolean validateNumberSize(Number value, Number minValue, Number maxValue){
		boolean result = true;
		if(!NumberHelper.isBetween(value, minValue, maxValue)){
			result = false;
		}
		return result;
	}

	private static boolean validateStringInvalidSymbols(String value){
		boolean result = true;
		if(StringHelper.containsAtLeast(value, StringHelper.INVALID_WEB_CHARACTERS)){
			result = false;
		}
		return result;
	}

	private static boolean validateStringInvalidLength(String value, int minLength, int maxLength){
		boolean result = true;
		if(!StringHelper.isLengthBetween(value, minLength, maxLength)){
			result = false;
		}
		return result;
	}

	/** Validate if the value string is an empty string. It retuns true, if value string is null or an empty string.
	 * Otherwise it returns false.
	 *
	 * @param value
	 * @return
	 */
	private static boolean validateStringEmpty(String value){
		boolean result = true;
		if(!StringHelper.isEmpty(value)){
			value = value.trim();
		}

		if(StringHelper.isEmpty(value)){
			result = false;
		}
		return result;
	}

	/** Validate emalAddress like a valid email between minLength and maxLength characters. If it is valid, it
	 * return true, otherwise it returns false.
	 *
	 * @param emailAddress
	 * @param minLentgh
	 * @param maxLentgh
	 * @return
	 */
	public boolean isValidEmailAddress(String emailAddress, Number minLentgh, Number maxLentgh){
		boolean result = false;
		result = isValidStringWithNumbers(emailAddress, minLentgh.intValue(), maxLentgh.intValue());

		result = isValidStringNotBeginWithNumbers(emailAddress) && result;

		if(result){
			List<String> strings = StringHelper.split(emailAddress, "@");

			/** The email haven't got two parts, the user email,and the server email. */
			if(strings.size() == 2){

				/** The email's user is too short. Or the server is too short. */
				if(	StringHelper.isLengthLowerOrEqualsThan(strings.get(0), 3) ||
					StringHelper.isLengthLowerOrEqualsThan(strings.get(1), 5) ){
					result = false;
				}
			} else {
				result = false;
			}
		}
		return result;
	}

	/** Validate url string like an url between a minLength and maxLength characters. If it is valid, it returns
	 * true, otherwise it returns false.
	 *
	 * @param url
	 * @param minLength
	 * @param maxLength
	 * @return
	 */
	public boolean isValidURL(String url, Number minLength, Number maxLength){
		boolean result = true;
		if(!StringHelper.isEmpty(url)){
			int pos = url.toLowerCase().indexOf(StringHelper.PREFIX_HTTP);

			if(pos != -1){
				String begin = url.substring(0, pos );
				String end = url.substring(pos + StringHelper.PREFIX_HTTP.length() , url.length());
				url = begin.concat(end);
			}
		}
		int countParts = 0;
		if(!StringHelper.isEmpty(url)){
			String auxHome = url.replace('.',' ');
			String[] pageParts = auxHome.split(" ");
			countParts = pageParts.length;
			for(int i = 0; i < countParts; i++){
				if(pageParts[i].length() < 2){
					result = false;
				}

			}
		}

		if(!result){
			return result;
		}

		if(!NumberHelper.isBetween(countParts, 1, 5)){
			result = false;
		}

		result = isValidStringWithNumbers(url, minLength.intValue(), maxLength.intValue()) && result;

		result = isValidStringNotBeginWithNumbers(url) && result;

		return result;
	}
}